package com.guanghua.brick.db;

import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.Map.Entry;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.guanghua.brick.html.Constant;

/**
 * 过滤条件对象的助手类
 * 主要用于POJO将转化为map类型
 * @author leeon
 */
public class QueryFilterHelper {
	
	private static final Log logger = LogFactory.getLog(QueryFilterHelper.class);
	
	//map容器
	private Map<String, Object> map = new HashMap<String, Object>();
	
	private QueryFilterHelper() {}
	
	//默认的构建器
	public QueryFilterHelper(Object pojo) {
		Method[] m = pojo.getClass().getDeclaredMethods();
		for (int i = 0; i < m.length; i ++) {
			//是一个合法geter
			if (m[i].getName().startsWith("get") && 
					m[i].getParameterTypes().length == 0 && 
					Modifier.isPublic(m[i].getModifiers()) &&
					!Modifier.isStatic(m[i].getModifiers())) {
				
				//获取属性名称
				String key = m[i].getName().substring(3);
				key = key.substring(0, 1).toLowerCase() + key.substring(1);
				
				//获取属性值并放入map
				try {
					map.put(key, m[i].invoke(pojo, (Object[])null));
				} catch (Exception e) {
					logger.error("init pojo map and invoke method error:" + key, e);
					map.put(key, null);
				}
				
			}
		}
	}

	public void clear() {
		map.clear();
	}

	public boolean containsKey(Object key) {
		return map.containsKey(key);
	}

	public boolean containsValue(Object value) {
		return map.containsValue(value);
	}

	public Set<Entry<String, Object>> entrySet() {
		return map.entrySet();
	}

	public Object get(Object key) {
		return map.get(key);
	}

	public boolean isEmpty() {
		return map.isEmpty();
	}

	public Set<String> keySet() {
		return map.keySet();
	}

	public Object put(String key, Object value) {
		return map.put(key, value);
	}

	public void putAll(Map<? extends String, ? extends Object> t) {
		map.putAll(t);
	}

	public Object remove(Object key) {
		return map.remove(key);
	}

	public int size() {
		return map.size();
	}

	public Collection<Object> values() {
		return map.values();
	}
	
	public Map<String, Object> toMap() {
		return this.map;
	}
	
	/**
	 * 通过req构造filter info，
	 * 通过提交上来的参数的前缀来寻找查询条件
	 * @param req
	 * @return
	 */
	public static Map<String, Object> newInstance(Map req) {
		return newInstance(req, Constant.GLOBE_FILTER, '_');
	}
	
	public static Map<String, Object> newInstance(Map req, String prefix) {
		return newInstance(req, prefix, '_');
	}
	
	public static Map<String, Object> newInstance(Map req, char delim) {
		return newInstance(req, Constant.GLOBE_FILTER, delim);
	}
	
	public static Map<String, Object> newInstanceWithoutPrefix(Map req) {
		Iterator key = req.keySet().iterator();
		Map<String, Object> ret = new HashMap<String, Object>();
		//循环所有的参数名称
		while (key.hasNext()) {
			String k = key.next().toString();
			Object v = validArray(req.get(k));
			//是filter查询条件
			if (v != null) {
				//放入
				ret.put(k, v);
			}
		}
		return ret;
	}
	
	public static Map<String, Object> newInstance(Map req, String prefix, char delim) {
		Iterator key = req.keySet().iterator();
		Map<String, Object> ret = new HashMap<String, Object>();
		//循环所有的参数名称
		while (key.hasNext()) {
			String k = key.next().toString();
			Object v = validArray(req.get(k));
			//是filter查询条件
			if (v != null && k.startsWith(prefix + String.valueOf(delim))) {
				//放入
				ret.put(k.substring(prefix.length()+1), v);
			}
		}
		return ret;
	}
	
	/**
	 * 主要用于将单个的String数组转为String
	 * 取String数组的第一个值
	 * @param o
	 * @return
	 */
	private static Object validArray(Object o) {
		if (o instanceof String[]) {
			if (((String[])o).length == 0) return null;
			else if (((String[])o).length == 1 && ((String[])o)[0] == null) return null;
			else if (((String[])o).length == 1 && ((String[])o)[0].trim().length() == 0) return null;
			else if (((String[])o).length == 1) return ((String[])o)[0];
			else return o;
		} else if (o instanceof String) {
			return o;
		} else {
			return null;
		}
	}
}
